package com.flyan.danmuhunter.common.datafactory;

import com.flyan.danmuhunter.common.utils.ThreadUtil;
import lombok.extern.slf4j.Slf4j;
import org.java_websocket.client.WebSocketClient;
import org.java_websocket.handshake.ServerHandshake;

import java.net.URI;

/**
 * 直播数据工厂，本类使用 web socket 客户端实现，用于收集直播间的直播数据并提供处理接口。
 * 对于不同的直播平台，实现该类快速开发数据工厂。
 *
 * @author flyan
 * @version 1.0
 * @date 2022/6/8
 */
@Slf4j
public abstract class LiveDataFactory
        extends WebSocketClient {

    protected final int heartbeatInterval;

    public LiveDataFactory(URI serverUri, int heartbeatInterval) {
        super(serverUri);
        this.heartbeatInterval = heartbeatInterval;
    }

    /**
     * 当 web socket 打开连接后，回调该函数。
     * 先进行身份验证，然后注册心跳任务。
     */
    @Override
    public void onOpen(ServerHandshake serverHandshake) {
        log.info("LiveDataFactory connected.");

        /* 发送认证数据包，连接成功要在 5 秒内发送认证 */
        if(!auth()) {
            log.error("Auth failed, closing...");
            this.close();
            return;
        }
        log.info("Auth OK.");

        /* 连接成功后每隔一点时间发送一个心跳包 */
        ThreadUtil.getPool().execute(() -> {
            try {
                /* 只有在 web socket 存活并打开的情况下才进行心跳发送 */
                while (isOpen()) {
                    heartbeat();
                    Thread.sleep(heartbeatInterval);
                }
                log.info("LiveDataFactory.Heartbeat task exit.");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
    }

    /**
     * 身份验证
     *
     * @return 验证结果
     */
    protected abstract boolean auth();

    /**
     * 向服务器发送心跳
     */
    protected abstract void heartbeat();

}
